package com.ruoyi.finance.rules.task;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.finance.rules.entity.SzOtherRule;
import com.ruoyi.finance.rules.entity.SzVipRule;
import com.ruoyi.finance.rules.mapper.SzOtherRuleMapper;
import com.ruoyi.finance.rules.mapper.SzVipRuleMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.*;

@Slf4j
@Component
public class SZRuleCache {

    @Autowired
    private SzVipRuleMapper vipRuleMapper;

    @Autowired
    private SzOtherRuleMapper otherRuleMapper;

    private volatile static SZRuleCache instance;
    private List<SzVipRule> vipRules;
    private SzOtherRule otherRule = null;
    private Timer timer;

    private SZRuleCache() {
        log.info("初始化数字人直播系统参数");
        vipRules = new ArrayList<>();
        otherRule = new SzOtherRule();
        timer = new Timer();
        scheduleRefreshTask();
    }

    public static SZRuleCache getInstance() {
        log.info("获取数字人直播系统参数实例");
        if (instance == null) {
            synchronized (SZRuleCache.class) {
                if (instance == null) {
                    log.warn("获取数字人直播系统参数实例-创建实例");
                    instance = new SZRuleCache();
                }
            }
        }
        return instance;
    }

    public List<SzVipRule> getVipRules() {
        if (vipRules.isEmpty()) {
            synchronized (this) {
                if (vipRules.isEmpty()) {
                    log.info("获取数字直播 代理等级规则表 为空，重新加载数据");
                    refreshData();
                }
            }
        }
        log.info("获取数字直播代理等级规则");
        return vipRules;
    }

    public SzOtherRule getOtherRule() {
        if (otherRule == null || otherRule.getId() == null) {
            synchronized (this) {
                if (otherRule == null || otherRule.getId() == null) {
                    log.info("获取数字直播 其它规则表数据 为空，重新加载数据");
                    refreshData();
                }
            }
        }
        log.info("获取数字直播其它规则");
        return otherRule;
    }


    private void scheduleRefreshTask() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 5);      // 设置为早上5点
        calendar.set(Calendar.MINUTE, 0);           // 设置为0分
        calendar.set(Calendar.SECOND, 0);           // 设置为0秒

        Date scheduledTime = calendar.getTime();
        if (scheduledTime.before(new Date())) {
            scheduledTime = addOneDay(scheduledTime);
        }

        TimerTask refreshTask = new TimerTask() {
            @Override
            public void run() {
                refreshData();
            }
        };

        // 每天早上5点执行刷新任务
        timer.schedule(refreshTask, scheduledTime, 24 * 60 * 60 * 1000); // 每24小时执行一次
    }

    private Date addOneDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_YEAR, 1);
        return calendar.getTime();
    }

    private void refreshData() {
        log.info("刷新数字人直播规则数据, {}", LocalDateTime.now());
        List<SzVipRule> refreshedVipRules = fetchVipRulesFromDatabase();
        SzOtherRule refreshedOtherRule = fetchOtherRuleFromDatabase();

        synchronized (this) {
            vipRules.clear();
            vipRules.addAll(refreshedVipRules);
            otherRule = refreshedOtherRule;
        }
    }

    private List<SzVipRule> fetchVipRulesFromDatabase() {
        if (vipRuleMapper != null) {
            return vipRuleMapper.selectList(new LambdaQueryWrapper<SzVipRule>().orderByAsc(SzVipRule::getSort));
        } else {
           throw new RuntimeException("加载数字人VIP缓存规则，vipRuleMapper未被实例化");
        }
    }

    private SzOtherRule fetchOtherRuleFromDatabase() {
        if (otherRuleMapper != null && otherRuleMapper.selectCount(new LambdaQueryWrapper<>()) != 0) {
            return otherRuleMapper.selectList(new LambdaQueryWrapper<>()).get(0);
        } else {
            throw new RuntimeException("加载数字人VIP缓存规则，otherRuleMapper未被实例化");
        }
    }

}
